package interfacesFerrovia;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Interface para acesso aos comandos da rede ferroviária.
 * @author Fernando Vanini
 *
 */

public interface ControleFerrovia extends DefsGlobais{
	
	/**
	 * Registra um tratador para os eventos gerados pela rede ferroviária.
	 * Pode-se registrar mais de um tratador
	 * @param tratador Objeto que implementa a interface TratadorDeEventos.
	 * @return true se o registro for feito normalmente.
	 */
	public boolean registraTratadorDeEventos(TratadorDeEventos tratador);
	
	/**
	 * Consulta aos elementos da rede. Retorna uma lista contendo os id's dos
	 * elementos da rede.
	 * @return lista contendo os id's dos elementos da rede.
	 */
	public String[] consultaElementos();
	
	/**
	 * Consulta os atributos fixos de um elemento da rede.
	 * @param idElemento identificação única do elemento.
	 * @return mapa <atributo,valor> contendo os atributos fixos do elemento.
	 */
	public Map<TipoAtributo,Object> consultaAtributosFixos(String idElemento);
	
	/**
	 * Consulta o estado (formado pelo conjunto de atributos variáveis) de
	 * um elemento da rede.
	 * @param idElemento identificação única do elemento.
	 * @return mapa <atributo,valor> que caracteriza o estado do elemento.
	 */
	public Map<TipoAtributo,Object> consultaEstado(String idElemento);
	
	/**
	 * Consulta um atributo de um elemento da rede.
	 * @param idElemento Identificação única do elemento
	 * @param atributo   Nome do atributo a ser consultado
	 * @return Object    Valor do atributo
	 */
	public Object consultaAtributo(String idElemento, TipoAtributo atributo);
	
	/**
	 * Consulta o conjunto de atributos de um dado elemento da rede.
	 * @param idElemento Identificação única do elemento da rede.
	 * @return Conjunto de atributos (fixos e variáveis) associados ao elemento.
	 */
	public Set<TipoAtributo> consultaListaDeAtributos(String idElemento);
	
	/**
	 * Comando para acelerar uma composicão.
	 * @param idComposicao Identificação única da composição.
	 * @param velocidade   Velocidade a ser atingida.
	 * @param urgente      Urgente(true) ou normal(false).
	 * @return             Tempo necessário para atingir a velocidade.
	 */
	public int acelerarComposicao(String idComposicao, float velocidade, boolean urgente);
	
	/**
	 * Comando para acelerar a composicao
	 * @param idComposicao  Identificação única da composição
	 * @param velocidade    Velocidade a ser atingida
	 * @param acel          Taxa de aceleração 
	 * @return              Tempo necessário para atingir a velocidade
	 */
	public int acelerarComposicao(String idComposicao, float velocidade, float acel);
	
	/**
	 * Comando para frear a composição.
	 * @param idComposicao Identificação única da composição.
	 * @param velocidade   Velocidade a ser atingida
	 * @param urgente      Urgente(true) ou normal(false).
	 * @return             Tempo necessário para realizar a operação.
	 */
	public int frearComposicao(String idComposicao, float velocidade, boolean urgente);
	
	/**
	 * Comando para frear a composição
	 * @param idComposicao Identificação única da composição.
	 * @param velocidade   Velocidade a ser atingida.
	 * @param fren         Taxa de frenagem aplicada.
	 * @return             Tempo necessário para realizar a operação.
	 */
	public int frearComposicao(String idComposicao, float velocidade, float fren);
	
	/**
	 * COnsulta a posição prevista para um instante futuro.
	 * @param idComposicao Identificação única da composição.
	 * @param instante Instante futuro a ser considerado.
	 * @return A posição prevista, no trecho atual.
	 */
	public float consultaPosicao(String idComposicao, int instante);
	
	/**
	 * Consulta o tempo previsto para atingir uma dada posição no trecho atual
	 * (considerando a velocidade e taxa de aceleração ou frenagem atuais).
	 * @param idComposicao Identificação única da composição.
	 * @param posicao Posição a ser atingida.
	 * @return Tempo estimado necessário para atingir a posição.
	 */
	public int consultaTempo(String idComposicao, float posicao);
	
	/**
	 * Calcula a distância mínima necessária à parada de uma composição.
	 * @param idComposicao Identificação única da composição.
	 * @return Distância mínima necessária à parada da composição.
	 */
	public float consultaDistMinParada(String idComposicao);

	@SuppressWarnings("unchecked")
	public List consultaCoordenadas(String idTrecho);
	
	/**
	 * Comando para mudar o estado de uma chave.
	 * @param idChave    Identificação única da chave
	 * @param idTrechoA  Identificação do trecho a ser conectado à extremidade A da chave.
	 * @param idTrechoB  Identificação do trecho a ser conectado à extremidade B da chave.
	 * @return           True se a operação pode ser realizada.
	 */
	public boolean mudarChave(String idChave, String idTrechoA, String idTrechoB);
	
	/**
	 * Define a resolução do relógio do simulador (intervalo entre tics).
	 * (default: 15s, habilitado = false)
	 * @param intervalo  Intervalo entre cada tic
	 * @param habilitado Indica se o simulador gera ou não o evento relativo ao tic.
	 */
	//public void defineTic(int intervalo, boolean habilitado);	 eliminado => será sempre 1 !!!!

	/**
	 * Define o cenário a ser usado na simulação.
	 * @param cenario Indica o cenário a ser usado (0..nCenarios-1)
	 */	
	public void defineCenario(int cenario);
	
	/**
	 *    Simula um cenário pré-definido, formado por um conjunto de elementos de rede.
	 *    @param t1 Instante de início da simulação (quase sempre zero).
	 *    @param t2 Instante de término da simulação.
	 * @throws Exception 
	 */
	public void simularCenario(int t1, int t2) throws Exception;
	
	

}
